package com.tgjorgoski.repository;

import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaUpdate;

public class HibernatePersistManager implements IPersistManager {
	private static Session session; 
	private static SessionFactory sessionFactory;
	private static Logger log = Logger.getLogger(HibernatePersistManager.class); 
	
	public static void init() {
		// Load Hibernate configuration
		Configuration config = new AnnotationConfiguration();
		config.configure();
		String dbName = com.tgjorgoski.window.Session.getDBFolder();
		dbName.replace('\\', '/');
		String connectionURL = "jdbc:derby:" + dbName + ";create=true";
		config.setProperty("hibernate.connection.url", connectionURL);

		new SchemaUpdate(config).execute(true, true);

		//used without annotations
		sessionFactory = config.buildSessionFactory();
		session = sessionFactory.openSession();
		log.info("Hibernate configuration finished");
	}
	
	public void saveObject(Object obj) {
		try {
			session.beginTransaction();
			session.saveOrUpdate(obj);
			session.flush();
			session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("Couldn't persist object:" + obj, e);
		}
	}

	public <E> List<E> getList(Class<E> cls) {
		session.beginTransaction();
		Query query = session.createQuery("FROM " + cls.getSimpleName());
		List<E> theList = query.list();
		session.getTransaction().commit();
		return theList;
	}

	public void disconnect() {
		session.disconnect();
	}

	public void deleteObject(Object obj) {
		try {
			session.beginTransaction();
			session.delete(obj);
			session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("Problem while deleting object:" + obj, e);
		}	
	}

	public <E> List<String> getUniqueValues(Class<E> cls, String propName) {
		session.beginTransaction();
		Query query = session.createQuery("select distinct " + propName + " FROM " + cls.getSimpleName());
		List<String> theList = query.list();
		session.getTransaction().commit();
		return theList;
	}

	public <E> E getBean(Class<E> cls, long id) {
		session.beginTransaction();
		Query query = session.createQuery("FROM " + cls.getSimpleName() + " WHERE id=" + id);
		List<E> theList = query.list();
		session.getTransaction().commit();
		if (theList!=null && theList.size()==1)
			return theList.get(0);
		else
			return null;
	}

	public <E> E getBean(Class<E> cls, String property, String value) {
		session.beginTransaction();
		Query query = session.createQuery("FROM " + cls.getSimpleName() + " WHERE " + property + "='" + value + "'");
		List<E> theList = query.list();
		session.getTransaction().commit();
		if (theList!=null && theList.size()==1)
			return theList.get(0);
		else
			return null;
	}

}
